package main;

import main.SQL.MsSQLConnect;
import main.Trees.SmetNode;
import main.reports.XLSReportProgressSmet;
import org.jdesktop.swingx.JXTreeTable;

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.sql.*;
import java.util.HashMap;

public class XLSLinkSmet extends Thread{

    private Connection connSQL;
    private Statement stat;
    private JDialog frame;
    private JList smetList;
    private DefaultListModel listModel;
    private HashMap<String, SmetNode> list;
    private HashMap<Integer, SmetNode> complexMap, objectMap, titulMap;
    private SmetNode root;
    private JXTreeTable showTree;

    public XLSLinkSmet() {
    }

    public void run() {
        chooseSmet();
        setComplex();
        frame.setVisible(true);
    }

    private void show() {

        JFrame showFrame = new JFrame();
        showFrame.setLayout(new GridBagLayout());
        GridBagConstraints c;

        int width = 950;
        int height = 1000;
        showFrame.setSize(new Dimension(width, height));
        Dimension screensize = Toolkit.getDefaultToolkit().getScreenSize();
        showFrame.setLocation(screensize.width / 2 - width / 2, screensize.height / 2 - height / 2);
        showFrame.setTitle("Отчет по привязанным сметам объекта " + listModel.getElementAt(smetList.getSelectedIndex()));

        XLSTreeModel xlsTreeModel = new XLSTreeModel();
        xlsTreeModel.openSmet(root);
        showTree = new JXTreeTable(xlsTreeModel);

        JScrollPane showscrollPane = new JScrollPane(showTree);

        JToolBar toolBar = new JToolBar();
        toolBar.setFloatable(false);
        c = new GridBagConstraints();
        c.gridx = 0;
        c.gridy = 0;
        c.fill = GridBagConstraints.BOTH;
        c.insets = new Insets(5, 15, 0, 15);
        showFrame.add(toolBar, c);

        Font font = new Font("Calibri", Font.PLAIN, 12);

        JButton saveToXLS = new JButton("Сохранить отчет");
        saveToXLS.setFont(font);
        saveToXLS.setFocusable(false);

        JLabel valuePercentComplex = new JLabel(root.getVolume().toString() + "%");
        valuePercentComplex.setFont(font);

        JLabel valueUseComplex = new JLabel(root.getSmNum());
        valueUseComplex.setFont(font);

        JLabel valueAllComplex = new JLabel(root.getUnit());
        valueAllComplex.setFont(font);

        JLabel textAllComplex = new JLabel("Всего по комплексу:   ");
        textAllComplex.setFont(font);

        JLabel textUseComplex = new JLabel("   Привязано:   ");
        textUseComplex.setFont(font);

        JLabel textPercentComplex = new JLabel(" %");
        textPercentComplex.setFont(font);

        toolBar.add(textAllComplex);
        toolBar.add(valueAllComplex);
        toolBar.add(new JToolBar.Separator());
        toolBar.add(textUseComplex);
        toolBar.add(valueUseComplex);
        toolBar.add(new JToolBar.Separator());
        toolBar.add(valuePercentComplex);
        toolBar.add(textPercentComplex);
        toolBar.add(new JLabel("                         "));
        toolBar.add(saveToXLS);

        saveToXLS.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent actionEvent) {
                XLSReportProgressSmet xrps = new XLSReportProgressSmet();
                xrps.generate(root);
            }
        });

        c = new GridBagConstraints();
        c.gridx = 0;
        c.gridy = 1;
        c.weightx = 1;
        c.weighty = 1;
        c.fill = GridBagConstraints.BOTH;
        c.insets = new Insets(5, 15, 15, 15);
        showFrame.add(showscrollPane, c);
        formatTaskSmetLinkTree();
        showFrame.setVisible(true);
    }

    //region Отображение диалога выбора комплекса
    private void chooseSmet() {
        frame = new JDialog();
        frame.setLayout(new GridBagLayout());
        frame.setModal(true);
        frame.setResizable(false);

        int width = 500;
        int height = 400;
        frame.setSize(new Dimension(width, height));
        Dimension screensize = Toolkit.getDefaultToolkit().getScreenSize();
        frame.setLocation(screensize.width / 2 - width / 2, screensize.height / 2 - height / 2);
        frame.setTitle("Отчет по привязанным сметам");

        frame.add(new JLabel("Выберите комплекс: "), new GridBagConstraints(0, 0, 2, 1, 0.1, 0.1, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(30, 30, 0, 30), 0, 0));

        GridBagConstraints c;

        listModel = new DefaultListModel();
        smetList = new JList(listModel);
        frame.add(new JScrollPane(smetList), new GridBagConstraints(0, 1, 2, 1, 0.1, 1, GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH, new Insets(3, 30, 0, 30), 0, 0));

        JButton ok = new JButton("Создать отчет");
        ok.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent actionEvent) {


//                createStructure(list.get(listModel.getElementAt(smetList.getSelectedIndex())).getId());
//                generateList(list.get(listModel.getElementAt(smetList.getSelectedIndex())).getId());
                countSmet();
                frame.setVisible(false);
                show();
//                generateXLS();
            }
        });
        frame.add(ok, new GridBagConstraints(0, 2, 1, 1, 10, 0.1, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(3, 30, 30, 3), 0, 0));

        JButton notOk = new JButton("Отмена");
        notOk.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent actionEvent) {
                frame.setVisible(false);
            }
        });
        frame.add(notOk, new GridBagConstraints(1, 2, 1, 1, 0.1, 0.1, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(3, 3, 30, 30), 0, 0));

    }
    //endregion

    //region Формирование дерева комплексов и списка для выбора
    private void setComplex() {

        this.connSQL = MsSQLConnect.ConnectDB("TST");

        this.list = new HashMap<>();
        this.complexMap = new HashMap<>();
        this.objectMap = new HashMap<>();
        this.titulMap = new HashMap<>();

        try {
            //загрузка списка для List
            stat = connSQL.createStatement();
            ResultSet rs = stat.executeQuery("SELECT complex_id, name FROM ks_Complex");
            while (rs.next()) {
                SmetNode curComplex = new SmetNode(0, rs.getInt("complex_id"), rs.getString("name"));
                this.list.put(curComplex.getName(), curComplex);
                this.complexMap.put(curComplex.getId(), curComplex);

                this.listModel.addElement(rs.getString("name"));
            }

            rs.close();
            stat.close();

            //Загрузка данных смет
            stat = connSQL.createStatement();
            ResultSet rs2 = stat.executeQuery("SELECT * FROM ks_Tituls");
            while (rs2.next()) {
                SmetNode curTitul = new SmetNode(rs2.getInt("complex_id"), rs2.getInt("titul_id"), rs2.getString("name"));
                curTitul.setType("smet");

                this.titulMap.put(curTitul.getId(), curTitul);
                this.complexMap.get(curTitul.getParentId()).add(curTitul);
            }

            rs.close();
            stat.close();


            stat = connSQL.createStatement();
            ResultSet rs3 = stat.executeQuery("SELECT * FROM ks_Objects");
            while (rs3.next()) {
                SmetNode curObject = new SmetNode(rs3.getInt("titul_id"), rs3.getInt("object_id"), rs3.getString("name"));
                curObject.isHeader = true;
                curObject.setType("smet");

                this.objectMap.put(curObject.getId(), curObject);
                this.titulMap.get(curObject.getParentId()).add(curObject);
            }

            rs.close();
            stat.close();

            connSQL.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }

    }
    //endregion

    public void countSmet() {

        this.root = this.complexMap.get(list.get(listModel.getElementAt(smetList.getSelectedIndex())).getId());

        connSQL = MsSQLConnect.ConnectDB("TST");

        try {
            stat = connSQL.createStatement();
            ResultSet rs = stat.executeQuery("SELECT sm.smet_id, count(distinct(l.smr_id)) as linked_count, count(distinct(r.smr_id)) as rows_count, sm.object_id, 'Смета ' + sm.smetNumber as smetNumber, sm.smetName\n" +
                    "\tfrom [TST].[dbo].[ks_Smeta] as sm\n" +
                    "\t\tleft join [TST].[dbo].[ks_Sm_section] as sect on sm.smet_id = sect.smet_id\n" +
                    "\t\tleft JOIN [TST].[dbo].[ks_Sm_rows] as r on r.sect_id = sect.sect_id\t\n" +
                    "\t\tleft join [Factage].[dbo].[link] as l on l.smr_id = r.smr_id\n" +
                    "\t\tleft join [TST].[dbo].[ks_Objects] as obj on sm.object_id = obj.object_id\n" +
                    "\t\tleft join [TST].[dbo].[ks_Tituls] as tit on tit.titul_id = obj.titul_id\n" +
                    "\t\t\n" +
                    "\twhere sm.smetIsSSR = 0 and tit.complex_id = " + root.getId()+ "\n" +
                    "\tgroup by sm.smet_id, sm.object_id, sm.smetNumber, sm.smetName");

            while (rs.next()) {

                SmetNode curSmet = new SmetNode(rs.getInt("object_id"), rs.getInt("smet_id"), "Смета " + rs.getString("smetNumber") + " - " + rs.getString("smetName"));
                curSmet.isString = true;
                curSmet.setUnit(rs.getString("rows_count"));
                curSmet.setSmNum(rs.getString("linked_count"));
                if (Integer.parseInt(curSmet.getUnit()) == 0) {
                    curSmet.setVolume(new BigDecimal(0));
                } else {
                    curSmet.setVolume(new BigDecimal(rs.getString("linked_count")).divide(new BigDecimal(rs.getString("rows_count")), 2, RoundingMode.HALF_UP).multiply(new BigDecimal(100)));
                }

                SmetNode curObject = objectMap.get(curSmet.getParentId());
                curObject.add(curSmet);
                curObject.setUnit( new BigDecimal(curObject.getUnit()!= null ? curObject.getUnit() : "0").add(new BigDecimal(curSmet.getUnit())).toString() );
                curObject.setSmNum ( new BigDecimal(curObject.getSmNum()!= null ? curObject.getSmNum() : "0").add(new BigDecimal(curSmet.getSmNum())).toString() );
                curObject.setVolume( new BigDecimal(curObject.getSmNum()).divide(new BigDecimal(curObject.getUnit()), 2, RoundingMode.HALF_UP).multiply(new BigDecimal(100)));

                SmetNode curTitul = titulMap.get(curObject.getParentId());
                curTitul.add(curObject);
                curTitul.setUnit( new BigDecimal(curTitul.getUnit()!= null ? curTitul.getUnit() : "0").add(new BigDecimal(curObject.getUnit())).toString() );
                curTitul.setSmNum ( new BigDecimal(curTitul.getSmNum()!= null ? curTitul.getSmNum() : "0").add(new BigDecimal(curObject.getSmNum())).toString() );
                curTitul.setVolume( new BigDecimal(curTitul.getSmNum()).divide(new BigDecimal(curTitul.getUnit()), 2, RoundingMode.HALF_UP).multiply(new BigDecimal(100)));

                root.setUnit( new BigDecimal(root.getUnit()!= null ? root.getUnit() : "0").add(new BigDecimal(curTitul.getUnit())).toString() );
                root.setSmNum ( new BigDecimal(root.getSmNum()!= null ? root.getSmNum() : "0").add(new BigDecimal(curTitul.getSmNum())).toString() );
                root.setVolume( new BigDecimal(root.getSmNum()).divide(new BigDecimal(root.getUnit()), 2, RoundingMode.HALF_UP).multiply(new BigDecimal(100)));

            }

            stat.close();
            rs.close();
            connSQL.close();

        } catch (SQLException e) {
            e.printStackTrace();
        }

    }

    private void formatTaskSmetLinkTree() {

        try {
            Image iconTask = ImageIO.read(getClass().getResource("images/leaf.png"));
            showTree.setLeafIcon(new ImageIcon(iconTask));
            Image iconWbs = ImageIO.read(getClass().getResource("images/wbs.png"));
            showTree.setOpenIcon(new ImageIcon(iconWbs));
            showTree.setClosedIcon(new ImageIcon(iconWbs));

        } catch (IOException e) {
            e.printStackTrace();
        }

        showTree.setRowHeight(20);
        showTree.setGridColor(new Color(219, 219, 219));
        showTree.setShowGrid(true, true);

        if (showTree.getColumnModel().getColumnCount() > 0) {
            showTree.getColumnModel().getColumn(0).setMinWidth(90);
            showTree.getColumnModel().getColumn(0).setPreferredWidth(90);
            showTree.getColumnModel().getColumn(1).setMinWidth(500);
            showTree.getColumnModel().getColumn(1).setPreferredWidth(800);
            showTree.getColumnModel().getColumn(2).setMinWidth(50);
            showTree.getColumnModel().getColumn(2).setPreferredWidth(50);
            showTree.getColumnModel().getColumn(3).setMinWidth(50);
            showTree.getColumnModel().getColumn(3).setPreferredWidth(50);
            showTree.getColumnModel().getColumn(4).setMinWidth(50);
            showTree.getColumnModel().getColumn(4).setPreferredWidth(50);
        }
    }

}
